#include "http_parser.h"
#include "http.h"
#include "../log.h"
#include "http11_parser.h"
#include "httpclient_parser.h"


#include <boost/concept_check.hpp>
#include <cstddef>
#include <cstring>
#include <memory>

namespace MYHTTP
{

constexpr uint64_t g_http_request_buffer_size = 4 * 1024;
constexpr uint64_t g_http_request_max_body_size = 64 * 1024 * 1024;
constexpr uint64_t g_http_response_buffer_size = 4 * 1024;
constexpr uint64_t g_http_response_max_body_size = 64 * 1024 * 1024;

//返回HttpRequest协议解析的缓存大小
uint64_t HttpRequestParser::GetHttpRequestBufferSize()
{
    return g_http_request_buffer_size;
}

//返回HttpRequest协议的最大消息体大小
uint64_t HttpRequestParser::GetHttpRequestMaxBodySize()
{
    return g_http_request_max_body_size;
}

//返回HttpResponse协议解析的缓存大小
uint64_t HttpResponseParser::GetHttpRequestBufferSize()
{
    return g_http_response_buffer_size;
}

//返回HttpResponse协议的最大消息体大小
uint64_t HttpResponseParser::GetHttpRequestMaxBodySize()
{
    return g_http_response_max_body_size;
}

//====================================================================================


//设置HTTP请求的方法名
void on_request_method(void *data, const char *at, size_t length) 
{
    //还原指针
    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    //还原HTTP方法枚举
    HttpMetHod m = CharsToHttpMethod(at);

    if(m == HttpMetHod::INVALID_METHOD)
    {
        log_error("invalid http request method: {}", std::string(at, length));
        parser->setError(1000);
        return;
    }

    parser->getData()->setMethod(m);
}

//uri 已经拆分为 fragment path query
void on_request_uri(void *data, const char *at, size_t length){}

//设置 http fragment 回调
void on_request_fragment(void *data, const char *at, size_t length) 
{
    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    parser->getData()->setFragment(std::string(at, length));
}

void on_request_path(void *data, const char *at, size_t length) 
{
    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    parser->getData()->setPath(std::string(at, length));
}

//设置HTTP请求的查询参数回调
void on_request_query(void *data, const char *at, size_t length) 
{
    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    parser->getData()->setQuery(std::string(at, length));
}

//设置HTTP请求的协议版本回调
void on_request_version(void *data, const char *at, size_t length) 
{
    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    uint8_t v = 0;
    if(strncmp(at, "HTTP/1.1", length) == 0)
    {
        v = 0x11;
    }
    else if (strncmp(at, "HTTP/1.0", length) == 0)
    {
        v = 0x10;
    }
    else
    {
        log_error("invalid http request version:{}", std::string(at, length));
        parser->setError(1001);
        return;
    }
    parser->getData()->setVersion(v);
}

void on_request_header_done(void *data, const char *at, size_t length) {}

//设置HTTP请求的头部参数回调
void on_request_http_field(void *data, const char *field, size_t flen
                           ,const char *value, size_t vlen) 
{
    if(flen == 0) 
    {
        log_error("invalid http request field length == 0");
        //parser->setError(1002);
        return;
    }

    HttpRequestParser* parser = static_cast<HttpRequestParser*>(data);
    parser->getData()->setHeader(std::string(field, flen)
                                ,std::string(value, vlen));
}


//——————————————————————————————————————————————————————————

HttpRequestParser::HttpRequestParser():m_error(0)
{
    m_data = std::make_shared<HttpRequest>();
    http_parser_init(&m_parser);

    //设置回调函数
    m_parser.request_method = on_request_method;
    m_parser.request_uri = on_request_uri;
    m_parser.fragment = on_request_fragment;
    m_parser.request_path = on_request_path;
    m_parser.query_string = on_request_query;
    m_parser.http_version = on_request_version;
    m_parser.header_done = on_request_header_done;
    m_parser.http_field = on_request_http_field;
    m_parser.data = this;
}

// 解析协议
size_t HttpRequestParser::execute(char* data, size_t len)
{
    size_t offset = http_parser_execute(&m_parser, data, len, 0);
    //将已经解析的部分覆盖掉
    memmove(data, data + offset, (len - offset));
    return offset;
}

//是否解析完成
int HttpRequestParser::isFinished()
{
    return http_parser_finish(&m_parser);
}

//是否有错误
int HttpRequestParser::hasError()
{
    return m_error || http_parser_has_error(&m_parser);
}

//获取消息体长度
uint64_t HttpRequestParser::getContentLength()
{
    return m_data->getHeaderAs<uint64_t>("content-length", 0);
}

//====================================================================================

//设置响应原因(状态文本)回调
void on_response_reason(void *data, const char *at, size_t length) 
{
    HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);
    parser->getData()->setReason(std::string(at, length));
}

//响应状态
void on_response_status(void *data, const char *at, size_t length) 
{
    HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);
    HttpStatus status = (HttpStatus)(atoi(at));
    parser->getData()->setStatus(status);
}

void on_response_chunk(void *data, const char *at, size_t length) {}

void on_response_version(void *data, const char *at, size_t length) 
{
    HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);
    uint8_t v = 0;
    if(strncmp(at, "HTTP/1.1", length) == 0) 
    {
        v = 0x11;
    } 
    else if(strncmp(at, "HTTP/1.0", length) == 0) 
    {
        v = 0x10;
    } 
    else 
    {
        log_error("invalid http response version: {}", std::string(at, length));
        parser->setError(1001);
        return;
    }

    parser->getData()->setVersion(v);
}

void on_response_header_done(void *data, const char *at, size_t length) {}

void on_response_last_chunk(void *data, const char *at, size_t length) {}

//头部参数
void on_response_http_field(void *data, const char *field, size_t flen
                           ,const char *value, size_t vlen) 
{
    HttpResponseParser* parser = static_cast<HttpResponseParser*>(data);
    if(flen == 0) 
    {
        log_error("invalid http response field length");
        //parser->setError(1002);
        return;
    }
    parser->getData()->setHeader(std::string(field, flen)
                                ,std::string(value, vlen));
}

//——————————————————————————————————————————————————————————

HttpResponseParser::HttpResponseParser():m_error(0)
{
    m_data = std::make_shared<HttpResponse>();
    httpclient_parser_init(&m_parser);

    m_parser.reason_phrase = on_response_reason;
    m_parser.status_code = on_response_status;
    m_parser.chunk_size = on_response_chunk;
    m_parser.http_version = on_response_version;
    m_parser.header_done = on_response_header_done;
    m_parser.last_chunk = on_response_last_chunk;
    m_parser.http_field = on_response_http_field;
    m_parser.data = this;
}

size_t HttpResponseParser::execute(char* data, size_t len, bool chunck)
{
    //如果数据包分块，将之前的数据清空从新解析数据
    if(chunck)
    {
        httpclient_parser_init(&m_parser);
    }
    size_t offset = httpclient_parser_execute(&m_parser, data, len, 0);

    memmove(data, data + offset, (len - offset));
    return offset;
}


//是否解析完成
int HttpResponseParser::isFinished()
{
    return httpclient_parser_finish(&m_parser);
}


//是否有错误
int HttpResponseParser::hasError()
{
    return m_error || httpclient_parser_has_error(&m_parser);
}


//获取消息体长度
uint64_t HttpResponseParser::getContentLength()
{
    return m_data->getHeaderAs<uint64_t>("content-length", 0);
}


}   //MYHTTP